package dao

import (
	"context"
	"fmt"

	"bilinadmin/pkg/db/redisex"

	jsoniter "github.com/json-iterator/go"
	"github.com/pkg/errors"

	"bilinadmin/internal/conf"
	"bilinadmin/pkg/db/pgex"
	"bilinadmin/pkg/mq"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

// DaoBase dao 定义
type DaoBase struct {
	cfg   *conf.Config
	db    *pgex.SqlEx
	nsq   *mq.NsqProducer
	cache *redisex.RedisEX
}

var daoBase *DaoBase

// InitDao 初始化 dao 基本定义
func InitDao(cfg *conf.Config, pgsql *pgex.SqlEx, cache *redisex.RedisEX, nsq *mq.NsqProducer) {
	daoBase = &DaoBase{
		db:    pgsql,
		nsq:   nsq,
		cache: cache,
		cfg:   cfg,
	}
}

// Transaction 开启数据库事务操作
func Transaction(ctx context.Context, capFunc func(ctx context.Context) (interface{}, error)) (interface{}, error) {
	return daoBase.db.StartCapsule(ctx, true, capFunc)
}

func isNil(err error) bool {
	return err.Error() == "redis: nil"
}

func (dao *DaoBase) needTrans(ctx context.Context) error {
	isTrans, err := dao.db.IsTrans(ctx)
	if err != nil {
		return err
	}
	if !isTrans {
		return errors.New("need enable transaction")
	}
	return nil
}

// CountNum 计算记录条数
func (dao *DaoBase) CountNum(ctx context.Context, condition string) (uint32, error) {
	// 计算数量
	var cnt uint32
	cntQ := fmt.Sprintf("SELECT COUNT(*) %s", condition)
	err := dao.db.Get(ctx, &cnt, cntQ)
	return cnt, err
}

func (d *DaoBase) BuildCacheKey(key string, params ...string) string {
	key = fmt.Sprintf("bilin-admin:%s", key)
	for _, p := range params {
		key += fmt.Sprintf(":%s", p)
	}
	return key
}
